#include<stdio.h>
#include<assert.h>
#include<string.h>
#include<sys/stat.h>
#include<dirent.h>

void findstr(char *path,char *str)
{
    FILE *f=fopen(path,"r");
    assert(f);
    char line[256];
    while(fgets(line,sizeof(line),f))
    {
        char *nl=strchr(line,'\n');
        if(nl!=NULL)
            *nl=0;
        if(strstr(line,str)!=NULL)
            printf("%s\n",line);
    }
    fclose(f);
}

void findstr2(char *path,char *str)
{
    FILE *f=fopen(path,"r");
    assert(f);
    char line[256];
    while(fgets(line,sizeof(line),f))
    {
        char *nl=strchr(line,'\n');
        if(nl!=NULL)
            *nl=0;
        if(strstr(line,str)!=NULL)
            printf("%s:%s\n",path,line);
    }
    fclose(f);
}

void findstr_r(char *path,char *str)
{
    DIR *dir=opendir(path);
    if(dir==NULL)
    {
        printf("DIR path error!\n");
        return;
    }
    struct dirent *entry;
    while(entry=readdir(dir))
    {
        if(strcmp(entry->d_name,".")==0)
            continue;
        else if(strcmp(entry->d_name,"..")==0)
            continue;
        else if(entry->d_type==DT_DIR)
        {
            char p[256];
            strcpy(p,path);
            strcat(p,"/");
            strcat(p,entry->d_name);
            findstr_r(p,str);
        }
        else if(entry->d_type==DT_REG)
        {
            char p[256];
            strcpy(p,path);
            strcat(p,"/");
            strcat(p,entry->d_name);
            findstr2(p,str);
        }
    }
    closedir(dir);
}

int main(int argc,char *argv[])
{
    if(argc<3 || argc>4)
    {
        printf("Instruction format error\n");
        return 0;
    }
    else if(argc==3)
    {
        struct stat attr;
        int flag=stat(argv[2],&attr);
        if(flag!=0)
        {
            printf("File path error\n");
            return 0;
        }
        if(S_ISDIR(attr.st_mode))
        {
            printf("%s: %s Is a drectory\n",argv[0],argv[2]);
            return 0;
        }
        else if(S_ISREG(attr.st_mode))
        {
            findstr(argv[2],argv[1]);
        }
    }
    else if(argc==4 && strcmp(argv[1],"-r")==0)
    {
        struct stat attr;
        int flag=stat(argv[3],&attr);
        if(flag!=0)
        {
            printf("File path error\n");
            return 0;
        }
        if(S_ISDIR(attr.st_mode))
        {
            findstr_r(argv[3],argv[2]);
            return 0;
        }
        else if(S_ISREG(attr.st_mode))
        {
            findstr(argv[3],argv[2]);
        }
    }
    else
    {
        printf("Instruction format error\n");
        return 0;
    }
    return 0;
}
